﻿using log4net;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Speech.Synthesis;

namespace FreeDream.Common
{
    public class VoiceHelper
    {
        static readonly ILog _logger = LogManager.GetLogger(typeof(VoiceHelper));
        static bool needStop = false;
        /// <summary>
        /// 语音对象List
        /// </summary>
        static List<SpeechSynthesizer> SpeechList = new List<SpeechSynthesizer>();
        /// <summary>
        /// 操作对象锁
        /// </summary>
        static object SpeechList_lock = new object();
        /// <summary>
        /// 开始语音播报
        /// </summary>
        /// <param name="voice_InputParam"></param>
        /// <returns></returns>
        public static General_ResponseParamModel Play(Voice_InputParamModel voice_InputParam, bool WriteLog = true)
        {
            try
            {
                Task.Run(() =>
                {
                    using (SpeechSynthesizer synth = new SpeechSynthesizer())
                    {
                        #region 监听暂停
                        lock (SpeechList_lock)
                        {
                            SpeechList.Add(synth);
                        }
                        #endregion

                        #region 设置语速
                        if (voice_InputParam.speed > 10 || voice_InputParam.speed < -10)
                        {
                            voice_InputParam.speed = 0;
                        }
                        synth.Rate = voice_InputParam.speed;
                        #endregion

                        #region 设置男女声
                        //检查语音参数合法性
                        if (voice_InputParam.gender > 1 || voice_InputParam.gender < 0)
                        {
                            voice_InputParam.gender = 0;
                        }
                        if (voice_InputParam.gender == 0)
                        {
                            synth.SelectVoiceByHints(VoiceGender.Male);
                        }
                        #endregion

                        #region 开始播报
                        if (voice_InputParam.txt != null && voice_InputParam.txt != "")
                        {
                            new List<string>(voice_InputParam.txt.Split(',')).ForEach((arg) =>
                            {
                                synth.Speak(arg);
                                Thread.Sleep(500);
                            });
                        }
                        #endregion

                        #region 播报完成
                        lock (SpeechList_lock)
                        {
                            SpeechList.Remove(synth);
                        }
                        #endregion
                    }

                });
                if (WriteLog)
                {
                    _logger.Info($"语音播报完成{voice_InputParam.ToString()}");
                }
                return new General_ResponseParamModel() { msg = "语音播报正常", success = true, status = Convert.ToInt32(FailCodeEnum.Normal.GetDescription()) };

            }
            catch (Exception ex)
            {
                _logger.Error($"语音播报异常{ex.Message} {voice_InputParam.ToString()}");
                return new General_ResponseParamModel() { msg = $"语音播报异常{ex.Message}", success = false, status = Convert.ToInt32(FailCodeEnum.Unknown.GetDescription()) };
            }
        }
        /// <summary>
        /// 语音播报暂停
        /// </summary>
        /// <returns></returns>
        public static General_ResponseParamModel Paused()
        {
            try
            {
                _logger.Info($"语音播报暂停开始");
                lock (SpeechList_lock)
                {
                    foreach (var item in SpeechList)
                    {
                        if (item != null)
                        {
                            item.Pause();
                        }
                    }
                    SpeechList.Clear();
                }
                _logger.Info($"语音播报暂停结束");
                return new General_ResponseParamModel() { msg = "语音播报停止正常", success = true, status = Convert.ToInt32(FailCodeEnum.Normal.GetDescription()) };
            }
            catch (Exception ex)
            {
                _logger.Error($"语音播报停止异常{ex.Message}");
                return new General_ResponseParamModel() { msg = $"语音播报停止异常{ex.Message}", success = false, status = Convert.ToInt32(FailCodeEnum.Unknown.GetDescription()) };
            }
        }

        /// <summary>
        /// 通用返回值参数模型
        /// </summary>
        public class General_ResponseParamModel
        {
            /// <summary>
            /// 操作状态 True||false
            /// </summary>
            public bool success { get; set; }
            /// <summary>
            /// 提示信息  操作成功
            /// </summary>
            public string msg { get; set; }
            /// <summary>
            /// 失败状态码
            /// 0 正常 接口调用成功，默认
            /// 101 硬件等待超时 硬件接口服务正常，但未识别到用户操作，接口返回失败状态
            /// 102 硬件调用失败 硬件接口服务正常，但调用硬件失败，接口返回失败状态
            /// 103 硬件服务占用 硬件接口服务正常，但其硬件服务执行中，接口返回 失败状态
            /// 104 其他 未能识别的其他失败情况
            /// </summary>
            public int status { get; set; }

            public override string ToString()
            {
                return $"语音播报返回值[操作状态:{success},提示信息:{msg},失败状态码:{status}]";
            }
        }

        /// <summary>
        /// 语音播报传入参数
        /// </summary>
        public class Voice_InputParamModel
        {
            /// <summary>
            /// 语音文本
            /// </summary>
            public string txt { get; set; }
            /// <summary>
            /// 0 男声；1 女生
            /// </summary>
            public int gender { get; set; }
            /// <summary>
            /// 播放速度；取值范围[-10,10]，0 为正常速度，负数为慢速，正数为快速
            /// </summary>
            public int speed { get; set; }

            public override string ToString()
            {
                return $"语音播报传入参数[语音文本:{txt}],[声音性别:{gender}],[播放速度:{speed}]";
            }
        }

        /// <summary>
        /// 失败状态码枚举（最终接口的返回值）
        /// </summary>
        public enum FailCodeEnum : int
        {
            /// <summary>
            /// 正常 接口调用成功，默认值
            /// </summary>
            [Description("0")]
            Normal,
            /// <summary>
            /// 硬件等待超时  硬件接口服务正常，但未识别到用户操作，接口返回失败状态
            /// </summary>
            [Description("101")]
            DeviceTimeOut,
            /// <summary>
            /// 硬件调用失败 硬件接口服务正常，但调用硬件失败，接口返回失败状态
            /// </summary>
            [Description("102")]
            DeviceFile,
            /// <summary>
            /// 硬件服务占用 件接口服务正常，但其硬件服务执行中，接口返回 失败状态
            /// </summary>
            [Description("103")]
            DeviceUsed,
            /// <summary>
            /// 其他 未能识别的其他失败情况 
            /// </summary>
            [Description("104")]
            Unknown,
        }
    }
}
